home *** CD-ROM | disk | FTP | other *** search
- /*
- * this is the driver for the password tester
- */
- #include "passwd.h"
-
- /*
- * file variables
- */
- int linect = 0; /* count of lines */
-
- /*
- * verify the password is okay
- */
- verify(ermsg)
- char ermsg[];
- {
- char buf[BUFSIZ]; /* input buffer */
- char passbuf[2*BUFSIZ]; /* buffer ater escape translation */
- FILE *fp; /* test file pointer */
- register char *p; /* used to append to passbuf[] */
- char *b; /* used to append to buf[] */
- char *sucmsg; /* message on failure */
-
- /*
- * set up the password and hostname
- */
- initpw();
-
- /*
- * open the file
- */
- if ((fp = fopen(pwtest, "r")) == NULL){
- if (errno < sys_nerr){
- LOG2(LG_SYSTEM, "%s: %s", pwtest, sys_errlist[errno]);
- }
- else
- LOG2(LG_SYSTEM, "%s: unknown error #%d",
- pwtest, errno);
- #ifdef DEFAULTTEST
- return(strlen(password) > 6 && atoi(findiv('v')->length) > 0);
- #else
- return(0);
- #endif
- }
-
- /*
- * now grab lines, replacing % and # as required
- */
- while(fgets(buf, BUFSIZ, fp) != NULL){
- /*
- * bump the line count
- */
- linect++;
- /*
- * see if it is a comment line; skip if so
- */
- if (buf[0] == '#')
- continue;
- /*
- * kill the newline if any
- */
- if (*(p = &buf[strlen(buf)-1]) == '\n')
- *p = '\0';
- /*
- * look for various special things
- */
- if (strncmp(buf, "GECOS:", 6) == 0 ||
- strncmp(buf, "SETGECOS:", 9) == 0){ /* gecos description */
- (void) loadgecos(&buf[6], CH_NULL, CH_NULL);
- continue;
- }
- if (strncmp(buf, "SIGCHARS:", 9) == 0){ /* significant chars */
- loadsig(&buf[9]);
- continue;
- }
- if (strncmp(buf, "SETVAR:", 7) == 0){ /* set variable */
- escape(&buf[7], passbuf);
- setvar(passbuf);
- continue;
- }
- if (strncmp(buf, "LOGLEVEL:", 9) == 0){ /* logging */
- loadlevel(&buf[9]);
- continue;
- }
- if (strncmp(buf, "FORCEGECOS:", 11) == 0) /* force gecos */
- continue;
- /*
- * an unescaped tab ends the test
- * and begins the error message
- */
- sucmsg = NULL;
- for(b = buf; (p = index(b, '\t')) != NULL &&
- (p != buf && p[-1] == '\\'); b = p);
- if (p != NULL){
- /*
- * move to the end of the white spaces;
- * the error message begins there
- */
- *p++ = '\0';
- while(isspace(*p))
- p++;
- if (*p != '\0')
- sucmsg = p;
- }
- /*
- * now for the escapes
- * go down the tests and interpolate all the escapes
- */
- escape(buf, passbuf);
-
- /*
- * pass the buffer to the tester
- */
- LOG2(LG_DEBUG, "testing buffer \"%s\" on line %d",
- passbuf, linect);
- if (passtest(passbuf) == 1){
- /*
- * it passed; return any error message
- * and close the file
- */
- if (sucmsg == NULL)
- ermsg[0] = '\0';
- else
- (void) strcpy(ermsg, sucmsg);
- (void) fclose(fp);
- LOG2(LG_ITEM, "failed (%s) on line %d",
- sucmsg, linect);
- return(0);
- }
- }
- /*
- * it failed; close the file
- * and return
- */
- (void) fclose(fp);
- return(1);
- }
-
- /*
- * this expands all escapes
- */
- escape(b, p)
- register char *b; /* input buffer */
- register char *p; /* expanded buffer */
- {
- register int n1, n2; /* begin, end position numbers */
- register int sgn; /* sign of escape */
- register int num; /* format field */
- register struct intvar *ip; /* points to variable storage */
- char *tb; /* passes address of reg variable */
-
- /*
- * do the required interpolations
- */
- for( ; *b; b++){
- /*
- * string escapes
- */
- if (*b == '%'){
- /*
- * get the sign if any
- */
- if (b[1] == '+' || b[1] == '-'){
- sgn = (b[1] == '-');
- b++;
- }
- else
- sgn = 0;
- /*
- * get the first number, if any
- */
- if (isdigit(b[1])){
- tb = b + 1;
- n1 = matoi(&tb)-1;
- b = tb - 1;
- /*
- * if a decimal point, a second
- * number may follow
- */
- if (b[1] == '.'){
- b++;
- if (isdigit(b[1])){
- tb = b + 1;
- n2 = matoi(&tb)-1;
- b = tb - 1;
- }
- else
- n2 = BUFSIZ;
- }
- else{
- /*
- * just a number -- number
- * of initial chars
- */
- n2 = n1;
- n1 = 0;
- }
- }
- else{
- /*
- * no numbers, just make limits BIG
- */
- n1 = 0;
- n2 = BUFSIZ;
- }
- /*
- * now look for number sign
- */
- switch(b[1]){
- case '^': /* all upper case */
- num = F_UPPER;
- b++;
- break;
- case '|': /* first letter cap */
- num = F_FIRST;
- b++;
- break;
- case '*': /* all lower case */
- num = F_LOWER;
- b++;
- break;
- case '#': /* associated number */
- num = F_NUMBER;
- b++;
- break;
- default: /* as is */
- num = F_ASIS;
- break;
- }
- ip = findiv(*++b);
- switch(ip->nstype){
- case TY_STR: /* string variable */
- p = sfmt(p, sgn, n1, n2, num,
- ip->string, ip->length);
- break;
- case TY_NUM: /* numeric variable */
- p = nfmt(p, sgn, ip->string, ip->length);
- break;
- }
- }
- /*
- * escaped char; just stuff the next one
- */
- else if (*b == '\\' &&
- (b[1] == '%' || b[1] == '#' || b[1] == '\\')){
- *++p = *++b;
- p++;
- }
- /*
- * something else; copy it
- */
- else
- *p++ = *b;
- }
-
- /*
- * close the buffer
- */
- *p = '\0';
- }
-